<script setup lang="ts">
import { getCurrentInstance, ref, onMounted, watch } from 'vue';
import { ElAvatar, ElInput, ElButton, ElRow, ElCol } from 'element-plus';
import { BubbleList } from 'vue-element-plus-x';
import type { BubbleListItemProps } from 'vue-element-plus-x/types/BubbleList';
import { Back } from '@element-plus/icons-vue';

const global = getCurrentInstance().appContext.config.globalProperties;

import { useRouter, useRoute } from "vue-router";

// 路由相关
const router = useRouter();
const route = useRoute();
const { query } = useRoute();

// 1. 接收路由参数（区分单聊/群聊）
const isGroupChat = ref(!!query.groupId); // 是否为群聊（有groupId则是）
const groupInfo = ref<{ id: string; name: string }>({
  id: query.groupId || '',
  name: query.groupName || '群聊'
});
const groupMembers = ref<string[]>([]); // 群成员ID列表

// 返回上一页
const goBackRouter = () => {
  router.go(-1);
};

const inputValue = ref(''); // 用于绑定输入框的响应式变量

// 定义 messages（响应式数组，存储聊天消息）
const messages = ref<BubbleListItemProps[]>([]); // 初始为空，后续添加实时消息

// 工具函数：从Token解析用户ID（根据实际Token结构调整字段）
const getUserIdFromToken = (token) => {
  if (!token) return '';
  try {
    const payloadBase64 = token.split('.')[1];
    const decoded = JSON.parse(atob(payloadBase64));
    return decoded.sub; // 假设用户ID存放在JWT的sub字段
  } catch (error) {
    console.error('Token解析失败:', error);
    return '';
  }
};


// 获取用户ID
const token = localStorage.getItem('token');
if (!token) {
  console.log('未检测到登录态(无token)，请先登录');
}
const userId = getUserIdFromToken(token); // 用户ID
if (!userId) {
  console.log("未获取到用户ID，请先登录");
} else {
  console.log("成功获取用户ID:" + userId);
}

// 用户信息
const userList = ref({
  id: '', // 用户ID
  username: '', // 用户名
  avatar: '', // 头像
  password: '',
  phone: '',
  gender: '',
  birthday: '',
  wechatNumber: '',
  signature: '',
  region: ''
});

// 根据userID查询用户信息
global.$http.get(`http://localhost:8030/user/selectAllById/${userId}`)
    .then(resp => {
      console.log(resp.data);
      userList.value = resp.data; // 将查询到的用户信息赋值给userList
      console.log("图片的url:", userList.value.avatar); // 用于测试
      // 同步用户头像和姓名到currentUser
      currentUser.value.avatar = userList.value.avatar;
      currentUser.value.name = userList.value.username;
    }).catch(err => {
  console.error('获取用户信息失败:', err);
});

// 好友信息
const friendList = ref({
  id: '', // 用户ID
  username: '', // 用户名
  avatar: '', // 头像
  password: '',
  phone: '',
  gender: '',
  birthday: '',
  wechatNumber: '',
  signature: '',
  region: ''
});

// 标记好友信息是否加载完成
const friendLoaded = ref(false);

// 仅单聊时查询好友信息
if (!isGroupChat.value && query.friendId) {
  // 根据friendId查询好友信息
  global.$http.get(`http://localhost:8030/user/selectAllById/${query.friendId}`)
      .then(resp => {
        console.log(resp.data);
        friendList.value = resp.data; // 将查询到的好友信息赋值给friendList
        // 同步好友头像和姓名到friend
        friend.value.id = friendList.value.id.toString();
        friend.value.avatar = friendList.value.avatar;
        friend.value.name = friendList.value.username;
        friendLoaded.value = true; // 加载成功，标记完成
      }).catch(err => {
    console.error('获取好友信息失败:', err);
    // 接口失败时，用路由参数兜底赋值（避免ID丢失）
    friend.value.id = query.friendId;
    friendLoaded.value = true; // 即使失败，兜底赋值后也标记完成
    console.log('好友信息加载失败，已使用默认ID');
  });
} else {
  // 群聊场景：标记好友加载完成（避免阻塞WebSocket初始化）
  friendLoaded.value = true;
}

// 实际数据（对接后端）
const currentUser = ref({
  id: userId,
  avatar: userList.value.avatar, // 头像
  name: userList.value.username
});

const friend = ref({
  id: query.friendId || '',
  avatar: friendList.value.avatar || '',
  name: friendList.value.username || ''
});

// 点击加号跳转
const addItem = () => {
  const targetId = isGroupChat.value ? groupInfo.value.id : query.friendId;
  if (targetId && userId) {
    router.push({
      name: 'VideoChat',
      query: { role: 'caller', targetUserId: targetId.toString() }
    });
  } else {
    alert('获取目标ID或用户ID失败，请重试');
  }
};

// 2. 加载群成员（群聊时调用，用于过滤已在群的好友）
const loadGroupMembers = async () => {
  if (!groupInfo.value.id) return;
  try {
    const resp = await global.$http.get(`http://localhost:8030/group/members/${groupInfo.value.id}`);
    // 假设后端返回格式为直接的成员ID数组或Result<Set<String>>
    groupMembers.value = resp.data.code === 200 ? resp.data.data : resp.data;
  } catch (err: any) {
    console.error('加载群成员失败:', err.message);
    // 即使加载失败，也继续显示邀请弹窗（但可能出现重复邀请）
  }
};


// 3. 加载群聊历史记录（群聊时调用）
const loadGroupChatHistory = async () => {
  if (!groupInfo.value.id) return;
  try {
    const resp = await global.$http.get(`http://localhost:8030/user/chat/group/history`, {
      params: { groupId: groupInfo.value.id }
    });
    const historyList = resp.data;
    if (!historyList.length) return;
    // 格式化群聊消息（比单聊多显示发送者名称）
    const formatMessages = historyList.map((item: any, index: number) => {
      const parsedItem = JSON.parse(item);
      return {
        key: index + Date.now(),
        role: parsedItem.senderId === userId ? 'user' : 'ai',
        placement: parsedItem.senderId === userId ? 'end' : 'start',
        content: parsedItem.content,
        senderName: parsedItem.senderName // 新增：发送者名称（群聊显示）
      };
    });
    messages.value = formatMessages;
  } catch (err) {
    console.error('加载群聊历史失败:', err);
  }
};

// WebSocket 实例（响应式存储）
const ws = ref<WebSocket | null>(null);

// 初始化 WebSocket 连接（适配群聊/单聊）
// 注意：删除了内部重复的`const initWebSocket = () => {`，仅保留一个函数定义
const initWebSocket = () => {
  const hasTargetId = isGroupChat.value ? !!groupInfo.value.id : !!friend.value.id;
  if (!userId || !hasTargetId || !token) {
    console.log(`用户ID、${isGroupChat.value ? '群ID' : '好友ID'}或Token缺失，暂不建立连接`);
    return;
  }

  // 1. 构造URL参数（仅传token和单聊的friendId）
  const wsParams = new URLSearchParams();
  wsParams.append('token', encodeURIComponent(token));
  if (!isGroupChat.value) {
    wsParams.append('friendId', friend.value.id);
  }

  // 2. 统一WebSocket路径（单聊/群聊共用/chat/{userId}）
  const wsUrl = `ws://localhost:8030/chat/${userId}?${wsParams.toString()}`;
  console.log(`即将建立${isGroupChat.value ? '群聊' : '单聊'}连接，URL：`, wsUrl);

  // 3. 预检请求：传递Authorization头（适配后端Token验证）
  const xhr = new XMLHttpRequest();
  xhr.open('GET', wsUrl.replace('ws://', 'http://'));
  xhr.setRequestHeader('Authorization', `Bearer ${token}`);
  xhr.send();

  // 4. 延迟创建WebSocket，确保Token被后端识别
  setTimeout(() => {
    ws.value = new WebSocket(wsUrl);

    // 连接成功回调
    ws.value.onopen = () => {
      console.log(`${isGroupChat.value ? '群聊' : '单聊'} WebSocket 连接成功`);
      isGroupChat.value ? loadGroupChatHistory() : loadChatHistory();
    };

    // 接收消息回调
    ws.value.onmessage = (e) => {
      try {
        const msgData = JSON.parse(e.data);
        console.log("收到消息：", msgData);
        // 群聊消息处理
        if (msgData.groupId && msgData.sender && msgData.content) {
          if (msgData.groupId === groupInfo.value.id) {
            messages.value.push({
              key: Date.now(),
              role: 'ai',
              placement: 'start',
              content: msgData.content,
              senderName: msgData.sender
            });
          }
          return;
        }
        // 单聊消息处理
        if (msgData.sender && msgData.content) {
          messages.value.push({
            key: Date.now(),
            role: 'ai',
            placement: 'start',
            content: msgData.content
          });
        }
      } catch (err) {
        console.error('解析消息失败:', err);
      }
    };

    // 关闭/错误回调
    ws.value.onclose = () => console.log(`${isGroupChat.value ? '群聊' : '单聊'} WebSocket 连接关闭`);
    ws.value.onerror = (err) => console.error('WebSocket 错误:', err);
  }, 100);
}; // 关键：补全函数闭合括号（之前因内层重复定义导致缺失）






// 加载单聊历史聊天记录
const loadChatHistory = () => {
  console.log('前端请求历史记录参数：', {
    userId: userId,
    friendId: friend.value.id,
    userIdType: typeof userId,
    friendIdType: typeof friend.value.id
  });

  if (!userId || !friend.value.id) {
    console.log('用户ID或好友ID缺失，无法加载历史记录');
    return;
  }

  global.$http.get(`http://localhost:8030/user/chat/history`, {
    params: {
      userId: userId,
      friendId: String(friend.value.id)
    }
  })
      .then(resp => {
        const historyList = resp.data;
        if (!historyList || historyList.length === 0) {
          console.log('暂无历史聊天记录');
          return;
        }

        const formatMessages = historyList.map((item: any, index: number) => {
          const parsedItem = JSON.parse(item);
          const senderId = parsedItem.senderId.toString();
          const currentUserId = userId.toString();
          return {
            key: index + Date.now(),
            role: senderId === currentUserId ? 'user' : 'ai',
            placement: senderId === currentUserId ? 'end' : 'start',
            content: parsedItem.content
          };
        });

        messages.value = formatMessages;
      })
      .catch(err => {
        console.error('加载历史消息失败:', err);
        console.log('历史聊天记录加载失败，请稍后重试');
      });
};

// 发送消息函数（区分群聊/单聊）
function sendMessage() {
  // 区分群聊/单聊：检查对应目标ID
  const targetId = isGroupChat.value ? groupInfo.value.id : friend.value.id;
  if (!targetId) {
    console.log(`未获取到${isGroupChat.value ? '群ID' : '好友ID'}，无法发送消息`);
    return;
  }
  if (!inputValue.value.trim() || !ws.value || ws.value.readyState !== WebSocket.OPEN) {
    console.log('消息为空或连接未就绪');
    return;
  }

  // 构造消息体
  const msg = isGroupChat.value
      ? {
        groupId: groupInfo.value.id,
        senderId: userId,
        senderName: currentUser.value.name,
        message: inputValue.value
      }
      : {
        toName: friend.value.id,
        senderId: userId,
        message: inputValue.value
      };

  // 发送消息
  ws.value.send(JSON.stringify(msg));
  console.log(`${isGroupChat.value ? '群聊' : '单聊'}发送消息：`, msg);

  // 本地添加自己的消息
  messages.value.push({
    key: Date.now(),
    role: 'user',
    placement: 'end',
    content: inputValue.value,
    senderName: isGroupChat.value ? currentUser.value.name : ''
  });
  inputValue.value = '';
}

// 监听关键参数变化，初始化WebSocket
watch(
    [() => userId, () => isGroupChat.value, () => groupInfo.value.id, () => friend.value.id, () => friendLoaded.value],
    () => {
      if (isGroupChat.value) {
        if (userId && groupInfo.value.id) initWebSocket();
      } else {
        if (userId && friend.value.id && friendLoaded.value) initWebSocket();
      }
    },
    { immediate: true }
);

// -------------------------- 新增：邀请好友相关逻辑 --------------------------
// 1. 邀请弹窗相关响应式变量
const inviteDialogVisible = ref(false); // 邀请弹窗显示状态
const allFriends = ref<{ id: string; name: string }[]>([]); // 所有好友列表（排除已在群的成员）
const selectedFriends = ref<string[]>([]); // 已选中的待邀请好友ID

// 2. 打开邀请弹窗（触发加载好友列表）
const openInviteDialog = () => {
  if (!groupInfo.value.id) {
    alert('群ID缺失，无法邀请');
    return;
  }
  // 先加载群成员（避免邀请已在群的人），再加载好友列表
  loadGroupMembers().then(() => {
    loadAllFriends(); // 加载当前用户的所有好友
    inviteDialogVisible.value = true; // 显示弹窗
  });
};

// 3. 加载当前用户的所有好友（适配新接口：http://localhost:8050/relation/friends）
const loadAllFriends = async () => {
  try {
    // 关键修改：使用新接口路径，传递当前用户ID作为参数
    const resp = await global.$http.get(`http://localhost:8050/relation/friends`, {
      params: { userId: userId } // 必须传递当前用户ID，供后端查询其好友
    });

    //打印获取的好友列表
    console.log("获取的好友列表信息",resp.data);

    // 关键修改：解析Result结构（后端返回格式：{code, msg, data}）
    if (resp.data.code === 200 && resp.data.data) {
      // 过滤已在群中的成员（避免重复邀请）
      allFriends.value = resp.data.data.filter(
          (friend: { id: string }) => !groupMembers.value.includes(friend.id)
      );
    } else {
      console.error('获取好友列表失败:', resp.data.msg || '未知错误');
      alert('获取好友列表失败：' + (resp.data.msg || '服务器异常'));
    }
  } catch (err: any) {
    console.error('获取好友列表网络错误:', err.message);
    alert('获取好友列表失败，请检查网络或后端服务');
  }
};

// 4. 执行邀请操作（调用后端/group/invite接口）
const doInviteFriends = async () => {
  if (!selectedFriends.value.length) {
    alert('请选择至少一位好友');
    return;
  }
  try {
    // 批量邀请（循环调用接口，若后端支持批量可优化为一次请求）
    const invitePromises = selectedFriends.value.map(friendId =>
        global.$http.post(`http://localhost:8030/group/invite`, null, {
          params: {
            groupId: groupInfo.value.id, // 群ID
            inviterId: userId, // 邀请者ID（当前用户）
            beInvitedUserId: friendId // 被邀请者ID
          }
        })
    );
    const results = await Promise.all(invitePromises);

    // 检查邀请结果（假设后端返回boolean或Result<boolean>）
    const allSuccess = results.every(res => res.data === true || (res.data?.code === 200 && res.data.data));
    if (allSuccess) {
      inviteDialogVisible.value = false;
      alert(`成功邀请${selectedFriends.value.length}位好友入群`);
      loadGroupMembers(); // 刷新群成员列表
      selectedFriends.value = []; // 清空选中状态
    } else {
      alert('部分好友邀请失败，请重试');
    }
  } catch (err: any) {
    console.error('邀请好友失败:', err.message);
    alert('邀请失败：' + err.message);
  }
};


// 5. 页面挂载时：群聊场景预加载群成员（为邀请时过滤用）
onMounted(() => {
  if (isGroupChat.value) {
    loadGroupMembers(); // 新增：群聊时提前加载成员，避免邀请弹窗加载延迟
  }
  // 原有页面卸载关闭WebSocket逻辑保留
  return () => {
    ws.value?.close();
  };
});
// -------------------------- 新增结束 --------------------------

</script>

<template>
  <div class="chat-container">
    <!-- 顶部：显示群名/好友名 + 新增“邀请好友”按钮（群聊场景） -->
    <div class="chat-header">
      <el-affix position="top" :offset="0">
        <el-row>
          <!-- 原有：返回图标列 -->
          <el-col :span="4" class="backIcon"> <!-- 调整：span从6→4，给邀请按钮腾空间 -->
            <el-icon @click="goBackRouter"><Back /></el-icon>
          </el-col>
          <!-- 原有：群名/好友名列 -->
          <el-col :span="14" class="friendName"> <!-- 调整：span从18→14，适配按钮列 -->
            <span class="friend-name">{{ isGroupChat ? groupInfo.name : friend.name }}</span>
          </el-col>
          <!-- 新增：邀请好友按钮列（仅群聊显示） -->
          <el-col :span="6" class="inviteBtn" v-if="isGroupChat">
            <el-button size="small" @click="openInviteDialog">邀请好友</el-button>
          </el-col>
        </el-row>
      </el-affix>
    </div>

    <!-- 中间：聊天消息区（群聊显示发送者名称） -->
    <div class="chat-messages">
      <BubbleList :list="messages">
        <template #avatar="{ item }">
          <el-avatar :src="item.role === 'user' ? currentUser.avatar : friend.avatar" size="small" />
        </template>
        <template #content="{ item }">
          <!-- 群聊：显示发送者名称（自己的消息不显示） -->
          <div v-if="isGroupChat && item.role !== 'user'" class="sender-name">{{ item.senderName }}</div>
          <div class="bubble-content" :class="{ start: item.placement === 'start', end: item.placement === 'end' }">
            {{ item.content }}
          </div>
        </template>
      </BubbleList>
    </div>

    <!-- 底部输入区 -->
    <el-affix position="bottom" :offset="0">
      <el-row class="footer-row">
        <!-- 语音 -->
        <el-col :span="2" class="">
          <img src="@/assets/HomePage/voice.svg" alt="语音" class="my-icon" />
        </el-col>
        <!-- 输入框 -->
        <el-col :span="12" class="">
          <el-input
              v-model="inputValue"
              placeholder="请输入消息..."
              class="input-box"
          />
        </el-col>
        <!-- 发送按钮 -->
        <el-col :span="4" class="sendButton">
          <el-button @click="sendMessage">发送</el-button>
        </el-col>
        <!-- 表情 -->
        <el-col :span="3" class="my-icon">
          <img src="@/assets/HomePage/smile.svg" alt="表情" class="my-icon1" />
        </el-col>
        <!-- 加号 -->
        <el-col :span="3" class="my-icon" @click="addItem">
          <img src="@/assets/HomePage/add.svg" alt="加号" class="my-icon2" />
        </el-col>
      </el-row>
    </el-affix>
    <!-- 新增：邀请好友弹窗（仅群聊场景可用） -->
    <!-- 4. 在这里插入邀请弹窗模板（新增） -->
    <el-dialog
        title="邀请好友入群"
        v-model="inviteDialogVisible"
        width="40%"
        :close-on-click-modal="false"
    >
      <div class="invite-content">
        <el-checkbox-group v-model="selectedFriends" class="friend-list">
          <el-checkbox
              v-for="friend in allFriends"
              :key="friend.id"
              :label="friend.id"
          >
            {{ friend.username  }}
          </el-checkbox>
        </el-checkbox-group>
        <div v-if="allFriends.length === 0" class="no-friend-tip">
          暂无可邀请的好友（已排除群内成员）
        </div>
      </div>
      <template #footer>
        <el-button @click="inviteDialogVisible = false">取消</el-button>
        <el-button type="primary" @click="doInviteFriends">确认邀请</el-button>
      </template>
    </el-dialog>




  </div>

</template>

<style scoped lang="less">
/* 整体布局 */
.chat-container {
  display: flex;
  flex-direction: column;
  height: 100vh;
  background: #f5f7fa;
}

/* 顶部：好友名称居中 */
.chat-header {
  padding: 12px 20px;
  background: #fff;
  border-bottom: 1px solid #ebeef5;
  .friend-name {
    font-size: 16px;
    font-weight: 500;
  }
}

// 返回图标
.backIcon {
  font-size: 19px;
}

// 好友名
.friendName {
  padding-left: 60px;
}

/* 中间：聊天区滚动 */
.chat-messages {
  flex: 1;
  overflow-y: auto;
  padding: 12px 20px;

  :deep(.bubble-list-item) {
    margin: 2px 0;
  }
}
:deep(.bubble-container) {
  box-shadow: none !important; /* 去除阴影，!important 确保优先级高于组件默认样式 */
}
/* 气泡内容样式 */
.bubble-content {
  font-size: 14px;
  border-radius: 2px;
  &.start {
    background: #FFFFFF; /* 别人的消息：白色背景 */
    color: #000; /* 文字黑色，确保清晰 */
  }
  &.end {
    background:  #FFFFFF; /* 自己的消息 */
    color: #000; /* 文字黑色 */
  }
}

/* 底部：输入区（水平布局） */
.footer-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 12px 20px;
  background: #fff;
  border-top: 1px solid #ebeef5;
  flex-wrap: nowrap;
}

/* 输入框：占满列宽 */
.input-box {
  flex: 1;
  width: auto;
}

/* 图标样式 */
.my-icon {
  max-width: 29px;
  height: auto;
  vertical-align: middle;
}
.my-icon1 {
  max-width: 36px;
  height: auto;
  padding-left: 5px;
}
.my-icon2 {
  max-width: 40px;
  height: auto;
  padding-left: 5px;
}

/* 群聊发送者名称样式 */
.sender-name {
  font-size: 12px;
  color: #909399;
  margin-bottom: 4px;
  margin-left: 8px;
}

// 新增：邀请按钮样式（右上角对齐）
.inviteBtn {
  text-align: right;
  padding-right: 10px;
  .el-button {
    font-size: 14px;
    padding: 4px 12px;
  }
}

// 新增：邀请弹窗内容样式
.invite-content {
  padding: 10px 0;
  .friend-list {
    display: flex;
    flex-direction: column;
    gap: 8px;
    max-height: 200px;
    overflow-y: auto;
  }
  .no-friend-tip {
    color: #909399;
    font-size: 14px;
    text-align: center;
    padding: 20px 0;
  }
}
</style>
